﻿using System;
using System.Web;
using System.Web.Mvc;

using Wiki.Web.Models;

namespace Wiki.Web.Controllers
{
    public sealed class PageController : Controller
    {
        [ControllerAction]
        public void Root()
        {
            if (Request.IsHttpMethod("POST"))
            {
                if (Request.IsSupportedMediaType("application/x-www-form-urlencoded"))
                {
                    WikiPage page = WikiPage.Query(Request.Form["title"]);
                    if (page.IsAvailable)
                    {
                        page = WikiPage.Edit(Request.Form["title"], Request.Form["body"]);
                        Response.SeeOther(Request.Url.AppendExtension("/" + page.Title), page.LastModified);
                    }
                    else
                    {
                        page = WikiPage.Edit(Request.Form["title"], Request.Form["body"]);
                        Response.Created(Request.Url.AppendExtension("/" + page.Title));
                    }
                }
                else
                {
                    Response.UnsupportedMediaType("application/x-www-form-urlencoded");
                }
            }
            else if (Request.IsHttpMethod("GET", "HEAD"))
            {
                if (Request.Accepts("text", "html"))
                {
                    Response.SeeOther(Request.Url.ToString("page", "page.html"));
                }
                else
                {
                    Response.NotAcceptable();
                }
            }
            else if (Request.IsHttpMethod("OPTIONS"))
            {
                Response.Options("GET, HEAD, OPTIONS, POST");
            }
            else
            {
                Response.MethodNotAllowed("GET, HEAD, OPTIONS, POST");
            }
        }

        [ControllerAction]
        public void Resource(string title)
        {
            WikiPage page = WikiPage.Query(title);
            if (Request.IsHttpMethod("DELETE"))
            {
                if (page.IsAvailable)
                {
                    WikiPage.Remove(title);
                    Response.NoContent();
                }
                else
                {
                    Response.NotFound();
                }
            }
            else if (Request.IsHttpMethod("GET", "HEAD"))
            {
                if (Request.Accepts("application", "xhtml+xml", false))
                {
                    if (page.IsAvailable)
                    {
                        Response.SeeOther(Request.Url.AppendExtension(".html"), page.LastModified);
                    }
                    else
                    {
                        Response.NotFound();
                    }
                }
                else if (Request.Accepts("application", "atom+xml", false))
                {
                    if (page.IsAvailable)
                    {
                        Response.SeeOther(Request.Url.AppendExtension(".atom"), page.LastModified);
                    }
                    else
                    {
                        Response.NotFound();
                    }
                }
                else if (Request.Accepts("text", "plain", false))
                {
                    if (page.IsAvailable)
                    {
                        Response.SeeOther(Request.Url.AppendExtension(".txt"), page.LastModified);
                    }
                    else
                    {
                        Response.NotFound();
                    }
                }
                else if (Request.Accepts("text", "html"))
                {
                    Response.SeeOther(Request.Url.AppendExtension(".html"), null as DateTime?);
                }
                else
                {
                    Response.NotAcceptable();
                }
            }
            else if (Request.IsHttpMethod("OPTIONS"))
            {
                Response.Options("GET, HEAD, OPTIONS");
            }
            else if (Request.IsHttpMethod("PUT"))
            {
                if (Request.IsSupportedMediaType("text/plain"))
                {
                    if (page.IsAvailable)
                    {
                        WikiPage.Edit(title, Request.InputStream.ReadString());
                        Response.NoContent();
                    }
                    else
                    {
                        WikiPage.Edit(title, Request.InputStream.ReadString());
                        Response.Created();
                    }
                }
                else
                {
                    Response.UnsupportedMediaType("text/plain");
                }
            }
            else
            {
                Response.MethodNotAllowed("GET, HEAD, OPTIONS, PUT");
            }
        }

        [ControllerAction]
        public void AtomRepresentation(string title)
        {
            if (Request.IsHttpMethod("GET", "HEAD"))
            {
                RenderView("AtomRepresentation", WikiPage.Query(title));
            }
            else
            {
                Response.MethodNotAllowed("GET, HEAD, OPTIONS");
            }
        }

        [ControllerAction]
        public void HtmlRepresentation(string title)
        {
            if (Request.IsHttpMethod("GET", "HEAD"))
            {
                RenderView("HtmlRepresentation", WikiPage.Query(title));
            }
            else
            {
                Response.MethodNotAllowed("GET, HEAD, OPTIONS");
            }
        }

        [ControllerAction]
        public void TxtRepresentation(string title)
        {
            if (Request.IsHttpMethod("GET", "HEAD"))
            {
                RenderView("TxtRepresentation", WikiPage.Query(title));
            }
            else
            {
                Response.MethodNotAllowed("GET, HEAD, OPTIONS");
            }
        }
    }
}